﻿using System;

namespace Fwql.Net.Extensions
{
    public static class RandomExtension
    {
        /// <summary>
        /// 随机Bool
        /// </summary>
        /// <param name="random"></param>
        /// <returns></returns>
        public static bool NextBool(this Random random)
        {
            return random.Next()%2 == 0;
        }

        /// <summary>
        /// 随机Bytes
        /// </summary>
        /// <param name="random"></param>
        /// <param name="length">长度</param>
        /// <returns></returns>
        public static byte[] NextBytes(this Random random, int length)
        {
            var data = new byte[length];
            random.NextBytes(data);
            return data;
        }

        /// <summary>
        /// 随机枚举值
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="random"></param>
        /// <returns></returns>
        public static T NextEnumValue<T>(this Random random) where T : struct
        {
            Type type = typeof (T);
            if (type.IsEnum == false)
                throw new InvalidOperationException();
            var array = Enum.GetValues(type);
            var index = random.Next(array.GetLowerBound(0), array.GetUpperBound(0) + 1);
            return (T) array.GetValue(index);
        }

        /// <summary>
        /// 随机UInt16
        /// </summary>
        /// <param name="random"></param>
        /// <returns></returns>
        public static UInt16 NextUInt16(this Random random)
        {
            return BitConverter.ToUInt16(random.NextBytes(2), 0);
        }

        /// <summary>
        /// 随机Int16
        /// </summary>
        /// <param name="random"></param>
        /// <returns></returns>
        public static Int16 NextInt16(this Random random)
        {
            return BitConverter.ToInt16(random.NextBytes(2), 0);
        }

        /// <summary>
        /// 随机Float
        /// </summary>
        /// <param name="random"></param>
        /// <returns></returns>
        public static float NextFloat(this Random random)
        {
            return BitConverter.ToSingle(random.NextBytes(4), 0);
        }

        /// <summary>
        /// 随机DateTime
        /// </summary>
        /// <param name="random"></param>
        /// <param name="minValue">最小边界</param>
        /// <param name="maxValue">最大边界</param>
        /// <returns></returns>
        public static DateTime NextDateTime(this Random random, DateTime minValue, DateTime maxValue)
        {
            var ticks = minValue.Ticks + (long) ((maxValue.Ticks - minValue.Ticks)*random.NextDouble());
            return new DateTime(ticks);
        }

        /// <summary>
        /// 随机DateTime
        /// </summary>
        /// <param name="random"></param>
        /// <returns></returns>
        public static DateTime NextDateTime(this Random random)
        {
            return NextDateTime(random, DateTime.MinValue, DateTime.MaxValue);
        }
    }
}